FIXED_POINT
Overview
The FIXED_POINT function finds a fixed point of a scalar function—a value x^* where f(x^*) = x^*. Fixed-point problems arise frequently in numerical analysis, economics, and engineering, where iterative processes naturally converge to stable equilibrium states. This implementation wraps SciPy’s scipy.optimize.fixed_point function.
The function accepts a mathematical expression as a string (e.g., cos(x) or sqrt(10/(x+3))), an initial guess, and iteration parameters. Starting from the initial guess x_0, the algorithm repeatedly applies the function until convergence is achieved within the specified tolerance.
Two iteration methods are available. The default del2 method uses Steffensen’s method with Aitken’s \Delta^2 convergence acceleration, which achieves quadratic convergence without requiring derivative calculations. Given three successive iterates x_n, x_{n+1}, and x_{n+2}, the accelerated estimate is computed as:
x_{n+3} = x_n - \frac{(x_{n+1} - x_n)^2}{x_{n+2} - 2x_{n+1} + x_n}
This acceleration technique, developed by Alexander Aitken in 1926, dramatically improves convergence for linearly converging sequences. The alternative iteration method performs simple fixed-point iteration without acceleration, which converges linearly when |f'(x^*)| < 1 near the fixed point.
The function validates convergence by checking that the residual |f(x^*) - x^*| is within the specified tolerance. Common applications include solving implicit equations, finding equilibrium points in dynamic systems, and iterative refinement algorithms. For more details, see the SciPy documentation and source code on GitHub.
This example function is provided as-is without any representation of accuracy.
Excel Usage
=FIXED_POINT(func_expr, x_zero, xtol, maxiter, fixed_point_method)
func_expr(str, required): String expression defining the function of x (e.g., ‘cos(x)’).x_zero(float, required): Initial guess for the fixed-point iteration.xtol(float, optional, default: 1e-8): Absolute tolerance for termination of the iteration. Must be positive.maxiter(int, optional, default: 500): Maximum number of iterations allowed. Must be a positive integer.fixed_point_method(str, optional, default: “del2”): Acceleration method for the fixed-point iteration.
Returns (float): Fixed-point value (float), or error message string.
Examples
Example 1: Cosine function fixed point
Inputs:
| func_expr | x_zero | xtol | maxiter | fixed_point_method |
|---|---|---|---|---|
| math.cos(x) | 0.5 | 1e-10 | 600 | del2 |
Excel formula:
=FIXED_POINT("math.cos(x)", 0.5, 1e-10, 600, "del2")
Expected output:
0.7390851332151607
Example 2: Linear affine function solution
Inputs:
| func_expr | x_zero |
|---|---|
| 0.25*x + 3 | 0 |
Excel formula:
=FIXED_POINT("0.25*x + 3", 0)
Expected output:
4
Example 3: Exponential decay fixed point
Inputs:
| func_expr | x_zero | xtol |
|---|---|---|
| math.exp(-x) | 0.7 | 1e-10 |
Excel formula:
=FIXED_POINT("math.exp(-x)", 0.7, 1e-10)
Expected output:
0.5671432904097838
Example 4: Linear function with simple iteration method
Inputs:
| func_expr | x_zero | maxiter | fixed_point_method |
|---|---|---|---|
| 1 + 0.3*x | 2 | 200 | iteration |
Excel formula:
=FIXED_POINT("1 + 0.3*x", 2, 200, "iteration")
Expected output:
1.4285714285714286
Python Code
import math
import re
import numpy as np
from scipy.optimize import fixed_point as scipy_fixed_point
def fixed_point(func_expr, x_zero, xtol=1e-08, maxiter=500, fixed_point_method='del2'):
"""
Find a fixed point x such that f(x) = x for a scalar function expression.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fixed_point.html
This example function is provided as-is without any representation of accuracy.
Args:
func_expr (str): String expression defining the function of x (e.g., 'cos(x)').
x_zero (float): Initial guess for the fixed-point iteration.
xtol (float, optional): Absolute tolerance for termination of the iteration. Must be positive. Default is 1e-08.
maxiter (int, optional): Maximum number of iterations allowed. Must be a positive integer. Default is 500.
fixed_point_method (str, optional): Acceleration method for the fixed-point iteration. Valid options: del2, iteration. Default is 'del2'.
Returns:
float: Fixed-point value (float), or error message string.
"""
# Validate func_expr
if not isinstance(func_expr, str):
return "Invalid input: func_expr must be a string."
if func_expr.strip() == "":
return "Invalid input: func_expr must be a non-empty string."
# Auto-convert caret (^) to double asterisk (**) for exponentiation ONCE
# This accommodates users familiar with mathematical notation
func_expr = re.sub(r'\^', '**', func_expr)
# Check for required variable reference using word boundary matching
if not re.search(r'\bx\b', func_expr):
return "Invalid input: func_expr must reference variable x (e.g., x)."
# Validate x_zero (accepts only float)
try:
x0 = float(x_zero)
except (TypeError, ValueError):
return "Invalid input: x_zero must be a float."
# Validate numeric parameters (ensure proper types)
if not isinstance(xtol, (int, float)):
return "Invalid input: xtol must be a numeric value."
if not isinstance(maxiter, (int, float)):
return "Invalid input: maxiter must be a numeric value."
xtol = float(xtol)
maxiter = int(maxiter)
if xtol <= 0:
return "Invalid input: xtol must be positive."
if maxiter <= 0:
return "Invalid input: maxiter must be positive."
# Validate method
valid_methods = ['del2', 'iteration']
if fixed_point_method not in valid_methods:
return f"Invalid input: fixed_point_method must be one of: {', '.join(valid_methods)}."
# Build safe globals dictionary for expression evaluation
safe_globals = {
"math": math, # Expose the math module itself
"np": np,
"numpy": np,
"__builtins__": {}, # Disable built-in functions for safety
}
# Add all math module functions
safe_globals.update({
name: getattr(math, name)
for name in dir(math)
if not name.startswith("_")
})
# Add common numpy/math function aliases
safe_globals.update({
"sin": np.sin,
"cos": np.cos,
"tan": np.tan,
"asin": np.arcsin,
"arcsin": np.arcsin,
"acos": np.arccos,
"arccos": np.arccos,
"atan": np.arctan,
"arctan": np.arctan,
"sinh": np.sinh,
"cosh": np.cosh,
"tanh": np.tanh,
"exp": np.exp,
"log": np.log,
"ln": np.log, # Natural log alias
"log10": np.log10,
"sqrt": np.sqrt,
"abs": np.abs,
"pow": np.power,
"pi": math.pi,
"e": math.e,
"inf": math.inf,
"nan": math.nan,
})
# Pre-validate the expression at the initial guess to catch parse/eval errors early
try:
initial_check = eval(func_expr, safe_globals, {"x": x0})
float(initial_check) # Verify it converts to float
except Exception as exc:
return f"Error: Invalid expression at initial guess: {exc}"
# Build function from expression
def func(x):
try:
return eval(func_expr, safe_globals, {"x": x})
except Exception as exc:
raise ValueError(f"Error evaluating func_expr: {exc}")
try:
result = scipy_fixed_point(func, x0=x0, xtol=xtol, maxiter=maxiter, method=fixed_point_method)
except Exception as exc:
return f"Error during fixed-point iteration: {exc}"
try:
value = float(result)
except (TypeError, ValueError):
return "Fixed-point iteration returned a non-scalar result."
if math.isnan(value) or math.isinf(value):
return "Fixed-point iteration failed: result is NaN or inf."
# Verify convergence by checking |f(value) - value|
try:
residual = abs(func(value) - value)
except Exception as exc:
return f"Error evaluating residual: {exc}"
if residual > xtol:
return f"Fixed-point iteration may not have converged: residual {residual} exceeds xtol {xtol}."
return value